package org.fas.utils
{
	
	
	/**
	* 	Class that contains static utility methods for manipulating and working
	*	with Arrays.
	* 
	*	Note that all APIs assume that they are working with well formed arrays.
	*	i.e. they will only manipulate indexed values.  
	* 
	* 	@langversion ActionScript 3.0
	*	@playerversion Flash 9.0
	*	@tiptext
	*/		
	public class FuArray
	{
		/**
		*	Determines whether the specified array contains the specified value.	
		* 
		* 	@param arr The array that will be checked for the specified value.
		*
		*	@param value The object which will be searched for within the array
		* 
		* 	@return True if the array contains the value, False if it does not.
		*
		* 	@langversion ActionScript 3.0
		*	@playerversion Flash 9.0
		*	@tiptext
		*/			
		public static function arrayContainsValue(arr:Array, value:Object):Boolean
		{
			return (arr.indexOf(value) != -1);
		}	
		
		/**
		*	Remove all instances of the specified value from the array,
		* 
		* 	@param arr The array from which the value will be removed
		*
		*	@param value The object that will be removed from the array.
		*
		* 	@langversion ActionScript 3.0
		*	@playerversion Flash 9.0
		*	@tiptext
		*/		
		public static function removeValueFromArray(arr:Array, value:Object):void
		{
			var len:uint = arr.length;
			
			for(var i:Number = len; i > -1; i--)
			{
				if(arr[i] === value)
				{
					arr.splice(i, 1);
				}
			}					
		}
		/**
		*	Create a new array that only contains unique instances of objects
		*	in the specified array.
		*
		*	Basically, this can be used to remove duplication object instances
		*	from an array
		* 
		* 	@param arr The array which contains the values that will be used to
		*	create the new array that contains no duplicate values.
		*
		*	@return A new array which only contains unique items from the specified
		*	array.
		*
		* 	@langversion ActionScript 3.0
		*	@playerversion Flash 9.0
		*	@tiptext
		*/	
		public static function createUniqueCopy(a:Array):Array
		{
			var newArray:Array = new Array();
			
			var len:Number = a.length;
			var item:Object;
			
			for (var i:uint = 0; i < len; ++i)
			{
				item = a[i];
				
				if(arrayContainsValue(newArray, item))
				{
					continue;
				}
				
				newArray.push(item);
			}
			
			return newArray;
		}
		
		/**
		*	Creates a copy of the specified array.
		*
		*	Note that the array returned is a new array but the items within the
		*	array are not copies of the items in the original array (but rather 
		*	references to the same items)
		* 
		* 	@param arr The array that will be copies
		*
		*	@return A new array which contains the same items as the array passed
		*	in.
		*
		* 	@langversion ActionScript 3.0
		*	@playerversion Flash 9.0
		*	@tiptext
		*/			
		public static function copyArray(arr:Array):Array
		{	
			return arr.slice();
		}
		
		/**
		*	Compares two arrays and returns a boolean indicating whether the arrays
		*	contain the same values at the same indexes.
		* 
		* 	@param arr1 The first array that will be compared to the second.
		*
		* 	@param arr2 The second array that will be compared to the first.
		*
		*	@return True if the arrays contains the same values at the same indexes.
			False if they do not.
		*
		* 	@langversion ActionScript 3.0
		*	@playerversion Flash 9.0
		*	@tiptext
		*/		
		public static function arraysAreEqual(arr1:Array, arr2:Array):Boolean
		{
			if(arr1.length != arr2.length)
			{
				return false;
			}
			
			var len:Number = arr1.length;
			
			for(var i:Number = 0; i < len; i++)
			{
				if(arr1[i] !== arr2[i])
				{
					return false;
				}
			}
			
			return true;
		}
		/**
		 * Array operation :delete a _item in _arr
		 * @param _array
		 * @param _item
		 * 
		 */		
		public static function del(_arr:Array,_item:Object):void{
			for(var i:uint=0;i<_arr.length;i++){
				if(_arr[i]==_item){
					_arr.splice(i,1);
				}
			}
		}
		/**
		 *  clear all item in a array
		 * @param _arr
		 * 
		 */		
		 public static function clear(_arr:Array):void{
		 	_arr.splice(0,_arr.length);
		 }
		/**
		 * set a item of array to top 
		 * @param _arr
		 * @param _i
		 * 
		 */		
		public static function toTop(_arr:Array,_i:uint):void{
			for(var i:uint=_i;i<_arr.length-1;i++){
				exchange(_arr,i,i+1);
			}
		}
		/**
		 *  
		 * @param _arr
		 * @param _i0
		 * @param _i1
		 * 
		 */		
		public static function exchange(_arr:Array,_i0:uint,_i1:uint):void{
			var _item:* = _arr[_i0];
			_arr[_i0] = _arr[_i1];
			_arr[_i1] = _item;
		}
		public static function delByAttr(_arr:Array,_attri:String,_value:*):int{
			for(var i:int=0;i<_arr.length;i++){
				if(_arr[i][_attri]==_value){
					_arr.splice(i,1);
					return i;
				}
			}
			return -1;
		}
		/**
		 * find a array by attribute = _value
		 * @param _arr
		 * @param _attr
		 * @param _value
		 * @return 
		 * 
		 */		
		public static function findsByAttr(_arr:Array,_attr:String,_value:*):Array{
			var _newArr:Array = new Array();
			for(var i:int=0;i<_arr.length;i++){
				if(_arr[i][_attr]==_value){
					_newArr.push(_arr[i]);
				}
			}
			return _newArr;
		}
		public static function sumOnAttr(_arr:Array,_attr:String):Number{
			var sum:Number = 0;
			for(var i:int=0;i<_arr.length;i++){
				sum += Number(_arr[i][_attr]);
			}
			return sum;
		}
		public static function sumOnAttrByCondition(_arr:Array,_attr:String,_attrConditon:String,_value:Object,_method:String='=='):Number{
			var sum:Number = 0;
			var _bl:Boolean;
			
			for(var i:int=0;i<_arr.length;i++){
//				trace('length',_arr.length,i);
				_bl=false;
				switch(_method){
					case '==':
						if(_arr[i][_attrConditon] == _value){
							_bl=true;
						}
						break;
					case '>=':
						if(Number(_arr[i][_attrConditon]) >= Number(_value)){
							_bl=true;
						}
						break;
					case '<=':
						if(_arr[i][_attrConditon] <= _value){
							_bl=true;
						}
						break;
					case '>':
						if(_arr[i][_attrConditon] > _value){
							_bl=true;
						}
						break;
					case '<':
						if(_arr[i][_attrConditon] < _value){
							_bl=true;
						}
						break;
					case '!=':
						if(_arr[i][_attrConditon] != _value){
							_bl=true;
						}
						break;
				}
				if(_bl){
					sum += Number(_arr[i][_attr]);
				}
			}
			return sum;
		}
		public static function findsByAttrs(_arr:Array,_attrs:Array,_values:Array):Array{
			var _newArr:Array = new Array();
			var _bl:Boolean;
			for(var i:int=0;i<_arr.length;i++){
				_bl = true;
				for(var j:int=0;j<_attrs.length;j++){
					if(_arr[i][_attrs[j]]!=_values[j]){
						_bl=false;
					}
				}
				if(_bl){
					_newArr.push(_arr[i]);
				}
			}
			return _newArr;
		}
		public static function findByAttr(_arr:Array,_attri:String,_value:*):Object{
			var _i:int = indexByAttr(_arr,_attri,_value);
			if(_i!=-1){
				return _arr[_i];
			}
			return null;
		}
		public static function indexByAttr(_arr:Array,_attri:String,_value:*):int{
			for(var i:int=0;i<_arr.length;i++){
				if(_arr[i][_attri]==_value){
					return i;
				}
			}
			return -1;
		}
		public static function compare(_arr1:Array,_arr2:Array,strict:Boolean = true):Array{
			var _r:Array = new Array();
			for(var i:int=0;i<_arr1.length;i++){
				if(indexOf(_arr2,Number(_arr1[i]),0,strict)!=-1){
					_r.push(_arr1[i]);
				}
			}
			return _r;
		}
		public static function indexOf(_arr:Array,searchElement:*,fromIndex:int=0,strict:Boolean = true):int{
			for(var i:int=fromIndex;i<_arr.length;i++){
				if(strict){
					if(_arr[i] == searchElement){
						return i;
					}
				}else{
					if(String(_arr[i]) == String(searchElement)){
						return i;
					}
				}
			}
			return -1;
		}
	}
}
